using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace FPLibrary
{
    [Serializable]
    public struct FPKeypoint
    {
        public Fix64 time;
        public Fix64 value;
    }

    //Cheap alternative of FPCurve, 
    [Serializable]
    public class FPPolyline
    {
        public FPKeypoint[] keys;

        public bool empty => !(keys != null && keys.Length > 0);

        public Fix64 Evaluate(Fix64 t)
        {
            if (keys == null)
                return Fix64.Zero;
            if (keys.Length <= 0)
                return Fix64.Zero;

            if (keys[keys.Length - 1].time <= t)
            {
                return keys[keys.Length - 1].value;
            }

            Fix64 segStartTime = 0;
            for (int i = 0; i < keys.Length; i++)
            {
                Fix64 segEndTime = keys[i].time;
                if (t < segEndTime)
                {
                    return FPMath.Lerp(
                        i == 0 ? Fix64.Zero : keys[i - 1].value,
                        keys[i].value,
                        (t - segStartTime) / (segEndTime - segStartTime));
                }

                segStartTime = segEndTime;
            }

            return keys[keys.Length - 1].value;
        }

        public Fix64 EvaluateDelta(Fix64 t1, Fix64 t2)
        {
            return t1 != 0 ? Evaluate(t2) - Evaluate(t1) : Evaluate(t2);
        }


        public static FPPolyline ToFPPolyline(AnimationCurve curve)
        {
            if (curve == null)
                return null;
            FPPolyline pline = new FPPolyline();
            pline.keys = new FPKeypoint[curve.length];
            for (int i = 0; i < curve.length; i++)
            {
                pline.keys[i] = new FPKeypoint() { time = curve.keys[i].time, value = curve.keys[i].value };
            }
            return pline;
        }
 #if UNITY_EDITOR
        public static AnimationCurve ToCurve(FPPolyline linex)
        {
            if (linex == null)
                return null;
            if (linex.keys != null && linex.keys.Length != 0)
            {
                var kfs = new Keyframe[linex.keys.Length];
                for (int i = 0; i < linex.keys.Length; i++)
                {
                    var fpkey = linex.keys[i];
                    kfs[i] = new Keyframe((float)fpkey.time, (float)fpkey.value);
                }
                var curve = new AnimationCurve(kfs);
                for (int i = 0; i < kfs.Length; i++)
                {
                    UnityEditor.AnimationUtility.SetKeyLeftTangentMode(curve, i, UnityEditor.AnimationUtility.TangentMode.Linear);
                    UnityEditor.AnimationUtility.SetKeyRightTangentMode(curve, i, UnityEditor.AnimationUtility.TangentMode.Linear);
                }
                return curve;
            }
            return null;
        }
#endif
    }
}